﻿using AMAP.ServiceInterfaces.Common;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;

namespace AMAP.ServiceClasses.Common
{
    public abstract class BaseRepositoryService<T> : BaseDatabaseService, IRepositoryService<T> where T : class
    {
        private readonly IDbSet<T> dbSet;

        protected BaseRepositoryService(IDatabaseFactory databaseFactory)
            : base(databaseFactory)
        {
            dbSet = dataContext.Set<T>();
        }

        public virtual IQueryable<T> GetAll()
        {
            return dbSet;
        }

        public virtual IQueryable<T> GetAllReadOnly()
        {
            return dbSet.AsNoTracking();
        }

        public virtual List<T> GetAllAsList()
        {
            return dbSet.ToList();
        }

        public virtual List<T> GetAllAsListReadOnly()
        {
            return dbSet.AsNoTracking().ToList();
        }

        public virtual T GetById(int id)
        {
            return dbSet.Find(id);
        }

        public virtual T GetById(long id)
        {
            return dbSet.Find(id);
        }

        public virtual T GetById(string id)
        {
            return dbSet.Find(id);
        }

        public virtual void Add(T entity)
        {
            this.AddWithoutSaving(entity);
            this.Save();
        }

        public virtual void Update(T entity)
        {
            this.UpdateWithoutSaving(entity);
            this.Save();
        }

        public virtual void Delete(int id)
        {
            this.DeleteWithoutSaving(id);
            this.Save();
        }

        public virtual void Delete(string id)
        {
            this.DeleteWithoutSaving(id);
            this.Save();
        }

        public virtual void AddWithoutSaving(T entity)
        {
            dbSet.Add(entity);
        }

        public virtual void UpdateWithoutSaving(T entity)
        {
            dataContext.Entry(entity).State = EntityState.Modified;
        }

        public virtual void DeleteWithoutSaving(int id)
        {
            T entity = this.GetById(id);
            dbSet.Remove(entity);
        }

        public virtual void DeleteWithoutSaving(string id)
        {
            T entity = this.GetById(id);
            dbSet.Remove(entity);
        }

        public virtual T Create()
        {
            return dbSet.Create<T>();
        }
    }
}
